package com.demo.webapp.kcfinder.utils;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.filefilter.AbstractFileFilter;

/**
 * 文件名过滤器代理
 * 
 * @author ryuu.kk
 *
 */
public class DelegateFileFilter extends AbstractFileFilter {

	/**
	 * 松散规则
	 * 松散规则下,只要有一个过滤器允许访问,则可以访问
	 */
	public static final int FILTER_RULE_ONE = 1;
	
	/**
	 * 多数规则
	 * 多数规则下,只有一半以上过滤器允许后,则可以访问
	 */
	public static final int FILTER_RULE_MAJOR = 2;
	
	/**
	 * 严格规则
	 * 严格规则下,必须完全匹配所有过滤规则,文件才被允许
	 */
	public static final int FILTER_RULE_STRICT = 8;
	
	/**
	 * 拒绝规则
	 * 严格规则下,必须完全匹配所有过滤规则,文件才被允许
	 */
	public static final int FILTER_RULE_REFUSE = 16;
	
	/**
	 * 默认使用1号规则
	 */
	private int allowRule = FILTER_RULE_ONE;
	
	private List<AbstractFileFilter> filenameFilterList;
	
	/**
	 * 构造函数
	 * @param filters 多个文件名过滤器
	 */
	public DelegateFileFilter(AbstractFileFilter... filters) {
		if (filters == null) {
			throw new RuntimeException("FilenameFilter is empty");
		}
		this.filenameFilterList = new ArrayList<AbstractFileFilter>();
		for (AbstractFileFilter filter : filters) {
			filenameFilterList.add(filter);
		}
	}
	
	/**
	 * 构造方法
	 * @param allowRule 允许规则号
	 * @param filters 多个文件名过滤器
	 */
	public DelegateFileFilter(int allowRule, AbstractFileFilter... filters) {
		this.allowRule = allowRule;
		if (filters == null) {
			throw new RuntimeException("FilenameFilter is empty");
		}
		this.filenameFilterList = new ArrayList<AbstractFileFilter>();
		for (AbstractFileFilter filter : filters) {
			filenameFilterList.add(filter);
		}
	}

	@Override
	public boolean accept(File dir, String name) {
		int allow = 0;
		int refuse = 0;
		boolean isAllow = false;
		for (FilenameFilter filter : filenameFilterList) {
			isAllow = filter.accept(dir, name);
			if (isAllow) {
				//仅有一个同意则允许访问
				if (allowRule == FILTER_RULE_ONE) {
					return true;
				}
				allow ++;
			} else {
				refuse ++;
			}
		}
		//其他匹配规则
		switch (allowRule) {
		case FILTER_RULE_MAJOR:
			return allow > refuse;
		case FILTER_RULE_STRICT:
			return allow == filenameFilterList.size();
		default:
			// em, error?
			return false;
		}
	}
}
